/*
 * Optimizator.java
 *
 * Created on 27 de abril de 2008, 05:42 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package adsi.optimization;
import adsi.domain.EntityException;
import adsi.persistence.DataServiceException;
import java.util.*;
import adsi.branchbound3.*;
import adsi.domain.EquipmentMaintenance;
import adsi.domain.Line;
import adsi.domain.ProgrammedMaintenance;
import adsi.persistence.DataServiceImpl;
import adsi.persistence.DataServiceModel;
/**
 *
 * @author Aramis
 */
public class Optimizator {
    private static final Optimizator instance = new Optimizator();
    
    private static int numLineas;
    private static List<Line> idLineas;
    private static int HOY=0;
    private static boolean ALARMA=false;
    private static Vector<Principal> principales = new Vector();
    private static Vector Tareas = new Vector();
    private static Vector<Tarea> NoProgramados = new Vector();
    private static Vector Programados = new Vector();
    private static List<EquipmentMaintenance> listaNoProgramados;
   
    /** Creates a new instance of Optimizator */
    private Optimizator() {

    }
    
    public synchronized static Optimizator getInstance() throws DataServiceException, EntityException {
        Mantenimientos m = new Mantenimientos();
        numLineas = m.getNumLineas();
        idLineas = m.getIdLineas();
        Calendar Today;
        Today = Calendar.getInstance(TimeZone.getTimeZone("Mexico/General"));
        Today.add(Calendar.SECOND, -1);
        HOY=Today.get(1)*365+(Today.get(2)+1)*30+Today.get(5);
        creaPrincipales();
        insertaNoModificables(m.regresaMantenimientosNoModificables());
        insertaModificables(m.regresaMantenimientosModificables());
        guarda();
        imprime();
        imprimeNoProgramados();
        return instance;
    }
    
    /**
     * @param args the command line arguments
     */
    static void guarda() throws DataServiceException, EntityException    
    {
        Vector<Tarea> tareas;
        ProgrammedMaintenance pm;
        EquipmentMaintenance em;
        DataServiceModel dsm = DataServiceImpl.getInstance();
        listaNoProgramados = new ArrayList<EquipmentMaintenance>();
        
        //planchamos tabla de programmed maintennance
        dsm.deleteAllPrograms();
        
        for(Principal prin: principales)
        {
            tareas = prin.getTareas();
            for(Tarea t: tareas) {
                pm = new ProgrammedMaintenance();
                pm.setStartDate(t.getRJ());
                pm.setLineID(prin.getID());
                pm.setEquipmentMaintenanceID(t.getNumTarea());
                
                dsm.saveProgrammedMaintenance(pm);
            }
        }
        
        for(Tarea t: NoProgramados) {
            em = dsm.retrieveEquipmentMaintenance(t.getNumTarea());
            listaNoProgramados.add(em);
        }
        
    }
    
    public synchronized static List<EquipmentMaintenance> getNotProgrammed() {
        return listaNoProgramados;
    }
    
    
    static void insertaNoModificables(Vector NoModificables)
    {
      for(int i=0;i<NoModificables.size();i++)
        {
            Tarea T =((Tarea) NoModificables.get(i));
            buscaLmaxMin(T,false);
            if (ALARMA)
            {
                System.out.println("Alarma. Mantenimiento " + T.getNumTarea() + " no pudo ser programado");
                NoProgramados.add(T);
                ALARMA=false;
            }
            else
                Programados.add(T);
        }
        
    }
    static void insertaModificables(Vector Modificables)
    {
        for(int i=0;i<Modificables.size();i++)
        {
            Tarea T =((Tarea) Modificables.get(i));
            buscaLmaxMin(T,true);
            if (ALARMA)
            {
                System.out.println("Alarma. Mantenimiento " + T.getNumTarea() + " no pudo ser programado");
                NoProgramados.add(T);
                ALARMA=false;
            }
            else
                Programados.add(T);
        }
        
    }
            
    static void creaPrincipales()
    {
        int i;
        for(i=0;i<numLineas;i++)
        {
            Principal p = new Principal(idLineas.get(i).getID());
            principales.add(i,p);
        }
    }
    static void buscaLmaxMin(Tarea T, boolean modif)
    {
        int i, imin=0, lmaxmin=1000, lmax=0;
        boolean insertado=false;
        while (!insertado && T.regresaRj()>HOY)
        {
           for(i=0;i<principales.size();i++)
           {
               ((Principal) principales.get(i)).insertaTarea(T);
               lmax=((Principal) principales.get(i)).obtenLmax();
               if(lmax<lmaxmin)
               {
                   lmaxmin=lmax;
                   imin=i;
               }
           }
           if(lmaxmin<=0)
           {
               insertado=true;
               System.out.println("Mantenimiento " + T.getNumTarea() + " Insertado en linea " + imin);
           }
           else
           {
               if(modif)
               {
                    eliminaExtras(-1,T);
                    T.decrementaRj();
               }
               else
               {    //Mantenimientos no modificable... no puede ser insertado...
                   insertado=true; //condici�n de salida del bucle...
                   imin=-1;
                   ALARMA=true;
               }
           }
        }
        /*condicion extrema*/
        if(!insertado)
        {
            ALARMA=true;
            eliminaExtras(-1,T);
            T.setProgramada(false);
        }
        else
        {
           eliminaExtras(imin,T);
           T.setProgramada(true);
        }
    }
    static void eliminaExtras(int imin, Tarea T)
    {
        int i;
        for(i=0;i<principales.size();i++)
        {
            if(i!=imin)
                ((Principal) principales.get(i)).eliminaTarea(T);
        }
    }
    
    static void imprime()
    {
        for(int i=0;i<principales.size();i++)
        {
            System.out.println("Linea " +i);
            ((Principal) principales.get(i)).imprimeTareas();
        }
    }
    static void imprimeNoProgramados()
    {
        if(NoProgramados.size()!=0)
        {
            System.out.println("Las siguientes tareas no pudieron ser programadas: ");
            for(int i=0;i<NoProgramados.size();i++)
            {
                Tarea t = (Tarea) NoProgramados.get(i);
                t.imprime();
            }
        }
        else
            System.out.println("Todas las tareas pudieron ser programadas");
        
    }
    
    public static void main(String[] args) throws EntityException, DataServiceException {
        Optimizator m = Optimizator.getInstance();
    }
}
